﻿using System;
using System.Collections.Generic;
using System.Xml;
using Framework;

namespace TemplateEngine
{
    internal static class FunctionHelper
    {
        private static Dictionary<string, ICommand> s_dict;
        private static object s_locker;

        static FunctionHelper()
        {
            s_locker = new object();
            s_dict = new Dictionary<string, ICommand>();
        }

        internal static object ExecuteFunction(string functionStr, XmlNode currentNode, TemplateNode tempalteNode)
        {
            int funIdx = functionStr.IndexOf("(");
            if (funIdx == -1)
            {
                throw new TemplateEngineException("函数定义错误，输入函数字符串" + functionStr);
            }

            // 获取处理函数对象
            string functionName = functionStr.Substring(0, funIdx);
            functionStr = functionStr.Trim();
            if (string.IsNullOrEmpty(functionName))
            {
                throw new TemplateEngineException("函数定义错误，输入函数字符串" + functionStr);
            }

            ICommand function = GetFunction(functionName);

            // 获取参数信息
            string argStr = functionStr.Substring(funIdx, functionStr.Length - funIdx);
            argStr = argStr.Trim();

            // 剔除两边圆括号
            argStr = argStr.Substring(1, argStr.Length - 2);

            // 处理函数参数
            string[] arrayArg = argStr.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            object[] args = new object[arrayArg.Length];
            for (int i = 0; i < arrayArg.Length; i++)
            {
                string arg = arrayArg[i];
                arg = arg.Trim();
                // 检查是否节点xpath
                if (arg.Substring(0, 1) == "{" && arg.Substring(arg.Length - 1, 1) == "}")
                {
                    string xpath = arg.Substring(1, arg.Length - 2);
                    var xmlNodeList = currentNode.SelectNodes(xpath);
                    args[i] = xmlNodeList;
                }
                else
                {
                    // 如果参数是字符串类型的，剔除引号
                    if (arg[0] == '\'' || arg[0] == '"')
                    {
                        arg = arg.Substring(1, arg.Length - 2);
                    }

                    args[i] = arg;
                }
            }

            return function.Execute(currentNode, tempalteNode, args);
        }

        private static ICommand GetFunction(string name)
        {
            name = name.ToLower();
            string topChar = name.Substring(0, 1);
            topChar = topChar.ToUpper();
            name = topChar + name.Substring(1, name.Length - 1);
            name += "Function";
            string nameSpace = "TemplateEngine.TranslateFunctions." + name;
            if (!s_dict.ContainsKey(nameSpace))
            {
                lock (s_locker)
                {
                    if (!s_dict.ContainsKey(nameSpace))
                    {
                        Type type = Type.GetType(nameSpace);
                        ICommand command = Activator.CreateInstance(type) as ICommand;
                        if (command == null)
                        {
                            throw new TemplateEngineException("函数" + name + "没有找到对应的处理程序");
                        }

                        s_dict.Add(nameSpace, command);
                    }
                }
            }

            return s_dict[nameSpace];
        }
    }
}
